package net.lcqf.tcp;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

// 匹配系统核心类
public class MatchmakingSystem {
    private static final int TEAM_SIZE = 5;
    private static final int MAX_WAIT_SECONDS = 30;

    // 线程安全队列‌:ml-citation{ref="7,8" data="citationList"}
    private final ConcurrentLinkedQueue<Player> waitQueue = new ConcurrentLinkedQueue<>();
    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

    // 启动匹配线程‌:ml-citation{ref="2,3" data="citationList"}
    public void start() {
        scheduler.scheduleAtFixedRate(this::matchPlayers, 0, 100, TimeUnit.MILLISECONDS);
    }

    // 添加玩家到队列‌:ml-citation{ref="6" data="citationList"}
    public void addPlayer(Player player) {
        waitQueue.offer(player);
    }

    private void matchPlayers() {
        List<Player> candidates = new ArrayList<>(waitQueue.size());

        // 取出当前队列所有玩家
        while (!waitQueue.isEmpty()) {
            candidates.add(waitQueue.poll());
        }

        // 按等待时间排序，优先处理等待久的玩家‌
        candidates.sort(Comparator.comparingLong(p -> p.getElo()));

        // 分组逻辑‌
        int index = 0;
        while (index + 2 * TEAM_SIZE <= candidates.size()) {
            List<Player> teamA = new ArrayList<>(TEAM_SIZE);
            List<Player> teamB = new ArrayList<>(TEAM_SIZE);

            // 选取相邻ELO范围的玩家‌:ml-citation{ref="1" data="citationList"}
            for (int i = 0; i < TEAM_SIZE; i++) {
                Player p = candidates.get(index + i);
                if (isValidMatch(p, candidates.get(index + TEAM_SIZE + i))) {
                    teamA.add(p);
                    teamB.add(candidates.get(index + TEAM_SIZE + i));
                } else {
                    // 匹配失败则回退
                    waitQueue.addAll(candidates.subList(index, candidates.size()));
                    return;
                }
            }

            // 触发匹配成功事件
            onMatchSuccess(new Team(teamA), new Team(teamB));
            index += 2 * TEAM_SIZE;
        }

        // 未匹配的玩家放回队列
        waitQueue.addAll(candidates.subList(index, candidates.size()));
    }

    // 判断是否有效匹配‌
    private boolean isValidMatch(Player p1, Player p2) {
        long waitTime = (System.currentTimeMillis() - p1.getJoinTime()) / 1000;
        int eloDiff = Math.abs(p1.getElo() - p2.getElo());

        // 等待越久，允许的ELO差异越大
        int maxAllowedDiff = waitTime > MAX_WAIT_SECONDS ? 200 : 100;
        return eloDiff <= maxAllowedDiff;
    }

    // 匹配成功回调
    private void onMatchSuccess(Team teamA, Team teamB) {
        // 实现游戏房间创建逻辑
        System.out.println("Matched teams:");
        System.out.println("TeamA: " + teamA);
        System.out.println("TeamB: " + teamB);
    }

    // 队伍对象
    static class Team {
        List<Player> players;
        int averageElo;

        Team(List<Player> players) {
            this.players = players;
            this.averageElo = (int) players.stream().mapToInt(Player::getElo).average().orElse(0);
        }
    }
}
